﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.IO;
using WMPLib;

namespace ClassicJukebox
{
    public class MediaViewModel
    {
        #region Public Properties

        public List<Album> Albums { get; set; }

        private ICommand nextAlbum;
        public ICommand NextAlbum 
        {
            get
            {
                if (this.nextAlbum == null)
                {
                    this.nextAlbum = new RelayCommand(this.NextAlbumExecute, this.NextAlbumCanExecute);
                }

                return this.nextAlbum;
            }
        }
        
        private ICommand previousAlbum;
        public ICommand PreviousAlbum 
        {
            get
            {
                if (this.previousAlbum == null)
                {
                    this.previousAlbum = new RelayCommand(this.PreviousAlbumExecute, this.PreviousAlbumCanExecute);
                }

                return this.previousAlbum;
            }
        }
        
        private ICommand songUp;
        public ICommand SongUp
        {
            get
            {
                if (this.songUp == null)
                {
                    this.songUp = new RelayCommand(this.SongUpExecute, this.SongUpCanExecute);
                }

                return this.songUp;
            }
        }

        private ICommand songDown;
        public ICommand SongDown
        {
            get
            {
                if (this.songDown == null)
                {
                    this.songDown = new RelayCommand(this.SongDownExecute, this.SongDownCanExecute);
                }

                return this.songDown;
            }
        }

        private ICommand playSong;
        public ICommand PlaySong 
        {
            get
            {
                if (this.playSong == null)
                {
                    this.playSong = new RelayCommand(this.PlaySongExecute, this.PlaySongCanExecute);
                }

                return this.playSong;
            }
        }

        #endregion

        #region Private Properties

        private ListCollectionView albumsCollectionView;
        private ListCollectionView tracksCollectionView;
        private MediaElement mediaElement = new MediaElement();
        private IMediaLibraryRepository repository;

        #endregion

        #region Ctor

        public MediaViewModel(IMediaLibraryRepository repository)
        {
            this.repository = repository;

            this.Initialize();

            this.albumsCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(this.Albums);
            this.albumsCollectionView.CurrentChanged += new EventHandler(this.AlbumsCollectionView_CurrentChanged);
            this.albumsCollectionView.CurrentChanging += new System.ComponentModel.CurrentChangingEventHandler(this.AlbumsCollectionView_CurrentChanging);

            Album a = (Album)this.albumsCollectionView.CurrentItem;
            if (a != null)
            {
                a.IsSelected = true;
                this.tracksCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(a.Tracks);
            }
            this.mediaElement.LoadedBehavior = MediaState.Manual;
            this.mediaElement.UnloadedBehavior = MediaState.Manual;
        }

        #endregion

        #region Private Methods

        private void AlbumsCollectionView_CurrentChanging(object sender, System.ComponentModel.CurrentChangingEventArgs e)
        {
            if (this.tracksCollectionView != null)
            {
                this.tracksCollectionView.MoveCurrentToFirst();
            }
        }

        private void AlbumsCollectionView_CurrentChanged(object sender, EventArgs e)
        {
            Album a = (Album)this.albumsCollectionView.CurrentItem;
            if (a != null)
            {
                this.tracksCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(a.Tracks);
                this.tracksCollectionView.MoveCurrentToFirst();
            }
        }

        private void Initialize()
        {
            this.Albums = this.repository.GetAlbums().ToList<Album>();
        }

        #region Command Event Delegates

        private bool NextAlbumCanExecute(object parameter)
        {
            return this.albumsCollectionView.CurrentPosition < (this.albumsCollectionView.Count - 1);
        }

        private void NextAlbumExecute(object parameter)
        {
            if (this.albumsCollectionView != null)
            {
                ((Album)this.albumsCollectionView.CurrentItem).IsSelected = false;
                this.albumsCollectionView.MoveCurrentToNext();
                ((Album)this.albumsCollectionView.CurrentItem).IsSelected = true;
            }
        }

        private bool PreviousAlbumCanExecute(object parameter)
        {
            return this.albumsCollectionView.CurrentPosition > 0;
        }

        private void PreviousAlbumExecute(object parameter)
        {
            if (this.albumsCollectionView != null)
            {
                ((Album)this.albumsCollectionView.CurrentItem).IsSelected = false;
                this.albumsCollectionView.MoveCurrentToPrevious();
                ((Album)this.albumsCollectionView.CurrentItem).IsSelected = true;
            }
        }

        private bool SongUpCanExecute(object parameter)
        {
            return this.tracksCollectionView.CurrentPosition > 0;
        }

        private void SongUpExecute(object parameter)
        {
            if (this.tracksCollectionView != null)
            {
                this.tracksCollectionView.MoveCurrentToPrevious();
            }
        }

        private bool SongDownCanExecute(object parameter)
        {
            return this.tracksCollectionView.CurrentPosition < (this.tracksCollectionView.Count - 1);
        }

        private void SongDownExecute(object parameter)
        {
            if (this.tracksCollectionView != null)
            {
                this.tracksCollectionView.MoveCurrentToNext();
            }
        }

        private bool PlaySongCanExecute(object parameter)
        {
            return this.tracksCollectionView.CurrentItem != null;
        }

        private void PlaySongExecute(object parameter)
        {
            Track track = (Track)this.tracksCollectionView.CurrentItem;

            this.mediaElement.Source = new Uri(track.Location);
            this.mediaElement.Play();
        }

        #endregion

        #endregion
    }
}
